home *** CD-ROM | disk | FTP | other *** search
- /*==============================================================================
-
- FICHERO: BMP.C
-
- AUTOR: ANTONIO LADESA JURADO
-
- FECHA: 24/6/94
-
- DESCRIPCION:
-
- Fichero que contiene las estructuras, constantes, variables y funciones
- internas y externas para el procesamiento de ficheros BMP.
-
- ==============================================================================*/
-
-
- /*---- MODULOS USADOS --------------------------------------------------------*/
-
- #include <stdio.h>
- #include <alloc.h>
- #include <string.h>
-
- #include "global.h"
- #include "memoria.h"
- #include "video.h"
- #include "bmp.h"
- #include "error.h"
-
-
- /*---- ESTRUCTURAS, CONSTANTES Y VARIABLES LOCALES AL MODULO -----------------*/
-
-
- /* cabecera de un fichero BMP */
- typedef struct
- {
- char tipo[2];
- long longitud;
- int reservados[2];
- long inicio;
- long tam;
- long ancho;
- long alto;
- int planos;
- int bitspixel;
- long compresion;
- long tamimagen;
- long x;
- long y;
- long colores;
- long usados;
- }CABbmp;
-
- /* cabecera del fichero BMP */
- static CABbmp cabecera;
-
-
- /*---- DEFINICION DE LAS FUNCIONES INTERNAS ----------------------------------*/
-
- IMAGEN *BMPleerCabecera(IMAGEN *c,FILE *f,char *nombre);
- IMAGEN *BMPleerImagen(IMAGEN *c,FILE *f);
- void BMPleerLinea(char *p, FILE *f,int bytes);
-
- void BMPescribirImagen(IMAGEN *c,FILE *f);
- void BMPescribirLinea(char *p, FILE *f,int bytes);
- void BMPcrearCabecera(IMAGEN *c);
-
- /*---- CODIFICACION DE LAS FUNCIONES OFRECIDAS -------------------------------*/
-
-
- /*---- FUNCION: extern IMAGEN *BMPcargar(char *nombre,IMAGEN *c) ---------------
-
- Descripción:
-
- Esta función carga en memoria una imagen de tipo BMP.
-
- Parámetros:
-
- char *nombre : nombre del fichero a cargar
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- extern IMAGEN *BMPcargar(char *nombre,IMAGEN *c)
- {
- FILE *f;
-
- /* abrir el fichero */
- if((f = fopen(nombre, "rb")) != NULL)
- {
- /* leer cabecera BMP */
- if((c = BMPleerCabecera(c,f,nombre))!=NULL)
- /* leer imagen */
- c = BMPleerImagen(c,f);
- fclose(f);
- }
- else
- {
- ERRORponer(ERRapertura);
- return(NULL);
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: extern int *BMPsalvar(char *nombre,IMAGEN *c) ------------------
-
- Descripción:
-
- Esta función salva en disco una imagen con formato BMP.
-
- Parámetros:
-
- char *nombre : nombre del fichero a salvar
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- Retorno:
-
- - 0 si hay error
- - 1 en caso contrario
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- /* salvar un fichero BMP */
- extern int BMPsalvar(char *nombre,IMAGEN *c)
- {
- /* puntero al fichero */
- FILE *f;
- /* contador */
- int i;
- /* puntero auxiliar a paleta */
- char *paux;
-
- /* abrir el fichero */
- if((f = fopen(nombre, "wb")) == NULL)
- {
- ERRORponer(ERRapertura);
- return(0);
- }
-
- /* crear la cabecera BMP */
- BMPcrearCabecera(c);
-
- /* escribir la cabecera BMP */
- if(fwrite((char *)&cabecera,1,sizeof(CABbmp),f) != sizeof(CABbmp))
- {
- ERRORponer(ERRescritura);
- fclose(f);
- return(0);
- }
-
- /* escribir paleta BMP */
- for(i=0,paux = c->paleta;i<c->colores;++i,paux+=3)
- {
- /* la paleta BMP está en formato BGRI */
- /* invertir RGB -> BGR */
- fputc(*(paux+2),f);
- fputc(*(paux+1),f);
- fputc(*paux,f);
- fputc(0,f);
- }
- /* escribir la imagen BMP */
- BMPescribirImagen(c,f);
- fclose(f);
- return(1);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- CODIFICACION DE LAS FUNCIONES INTERNAS --------------------------------*/
-
-
- /*---- FUNCION: IMAGEN *BMPleerCabecera(IMAGEN *c,FILE *f,char *nombre) --------
-
- Descripción:
-
- Esta función reserva memoria para la imagen y lee la cabecera del fichero
- BMP.
-
- Parámetros:
-
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
- char *nombre : nombre del fichero a cargar
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- IMAGEN *BMPleerCabecera(IMAGEN *c,FILE *f,char *nombre)
- {
- int i;
- char *paux;
-
- /* lectura de la cabecera */
- if(fread((char *)&cabecera,1,sizeof(CABbmp),f) == sizeof(CABbmp))
- {
- /* comprobar que es BMP */
- if(memcmp(cabecera.tipo,"BM",2) || cabecera.planos != 1
- || cabecera.compresion)
- {
- ERRORponer(ERRnoTratado);
- return(NULL);
- }
- }
- else
- {
- ERRORponer(ERRlectura);
- return(NULL);
- }
-
- /* reservar memoria para la cabecera de trabajo */
- if((c=MEMreservarCAB(c))==NULL)
- {
- ERRORponer(ERRnoMemoria);
- return(NULL);
- }
-
- /* cargar cabecera de trabajo */
- strcpy(c->nombre,nombre);
- c->ancho= (int)cabecera.ancho;
- c->alto = (int)cabecera.alto;
- c->formato = BMP;
- /* determinar tipo de imagen */
- switch(cabecera.bitspixel)
- {
- /* monocromática */
- case 1:
- c->modo = VIDEOmono;
- c->bytes = DePixelsABytes(c->ancho);
- c->colores = 2;
- c->haypaleta = FALSO;
- break;
-
- /* 16 colores, se guarda como VGA */
- case 4:
- c->modo = VIDEOvga;
- c->bytes = c->ancho;
- c->colores = 16;
- c->haypaleta = CIERTO;
- break;
-
- /* 256 colores */
- case 8:
- c->modo = VIDEOvga;
- c->bytes = c->ancho;
- c->colores = 256;
- c->haypaleta = CIERTO;
- break;
-
- /* formato desconocido */
- default:
- ERRORponer(ERRnoTratado);
- c = MEMliberar(c);
- return(NULL);
- }
-
- /* si existe paleta, cargarla */
- if(cabecera.colores == 0 && cabecera.bitspixel != 1)
- {
- for(i=0,paux = c->paleta;i<c->colores;++i,paux+=3)
- {
- /* la paleta tiene 4 componentes: BGRI */
- fread((char *)paux,3,1,f);
- /* el cuarto se desecha */
- fgetc(f);
- }
- /* la paleta viene invertida (RGB <-> BGR) */
- memcpy(c->paleta,VIDEOinvertirPaleta(c->paleta,c->colores),c->colores*3);
- }
-
- /* si no hay memoria para la imagen, liberar cabecera */
- if(!MEMreservar(c))
- {
- c =MEMliberar(c);
- ERRORponer(ERRnoMemoria);
- return(c);
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: IMAGEN *BMPleerImagen(IMAGEN *c,FILE *f) -----------------------
-
- Descripción:
-
- Esta función carga en memoria una imagen de tipo BMP.
-
- Parámetros:
-
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
-
- Retorno:
-
- Puntero a la estructura de la imagen
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- IMAGEN *BMPleerImagen(IMAGEN *c,FILE *f)
- {
- /* contadores */
- int i,j,n;
- /* buffers */
- char p[1024];
- char q[1024];
-
- /* posicionar puntero al inicio de la imagen */
- fseek(f,cabecera.inicio,SEEK_SET);
-
- /* cargar imagen */
- for(i = c->alto-1; i >= 0;--i)
- {
- /* si es de 16 colores, de cada byte se extraen 2 pixels */
- if( cabecera.bitspixel == 4)
- {
- BMPleerLinea(p,f,c->bytes/2);
- for(j=0,n=0;j<c->bytes/2;j++,n+=2)
- {
- q[n+1] = p[j] & 0x0f;
- q[n] = (p[j] & 0xf0) >> 4;
- }
- MEMescribir(q,i,c);
- }
- else
- {
- /* si es monocroma o vga, se lee normalmente */
- BMPleerLinea(p,f,c->bytes);
- MEMescribir(p,i,c);
- }
- }
- return(c);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void BMPleerLinea(char *p, FILE *f,int bytes) ------------------
-
- Descripción:
-
- Esta función lee una línea de un fichero BMP.
-
- Parámetros:
-
- char *p : puntero a buffer donde se almacena la línea
- FILE *f : puntero al fichero
- int bytes: numero de bytes por linea
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- void BMPleerLinea(char *p, FILE *f,int bytes)
- {
- fread(p,bytes,1,f);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void BMPcrearCabecera(IMAGEN *c) -------------------------------
-
- Descripción:
-
- Esta función crea una cabecera BMP.
-
- Parámetros:
-
- IMAGEN *c : puntero a estructura que alberga la imagen
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- void BMPcrearCabecera(IMAGEN *c)
- {
- /* relleno de la cabecera */
- strcpy(cabecera.tipo,"BM");
- cabecera.reservados[0] = cabecera.reservados[1] = 0;
- cabecera.inicio = sizeof(CABbmp) + (c->colores * 4);
- cabecera.tam = 40;
- cabecera.ancho = c->ancho;
- cabecera.alto = c->alto;
- cabecera.planos = 1;
- cabecera.longitud = cabecera.inicio + (c->alto * c->bytes);
- switch(c->modo)
- {
- case VIDEOmono:cabecera.bitspixel = 1;break;
- case VIDEOega:cabecera.bitspixel = 4;break;
- case VIDEOvga:cabecera.bitspixel = 8;break;
- };
- cabecera.compresion = cabecera.tamimagen = cabecera.x = cabecera.y =
- cabecera.colores = cabecera.usados = 0;
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void BMPescribirImagen(IMAGEN *c,FILE *f) ----------------------
-
- Descripción:
-
- Esta función graba la imagen en un fichero BMP.
-
- Parámetros:
-
- IMAGEN *c : puntero a estructura que alberga la imagen
- FILE *f : puntero al fichero
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- void BMPescribirImagen(IMAGEN *c,FILE *f)
- {
- /* contador de líneas */
- int i;
- /* buffers */
- char p[1024];
- char q[1024];
-
- /* salvar imagen */
- for(i = c->alto-1; i >= 0;--i)
- {
- /* si el modo es ega, convertir los bits de plano a pixel */
- if(c->modo == VIDEOega)
- {
- MEMleer(q,i,c);
- EGAdePlanoaPixel(q,p,c->ancho);
- BMPescribirLinea(p,f,c->bytes);
- }
- else
- {
- MEMleer(p,i,c);
- BMPescribirLinea(p,f,c->bytes);
- }
- }
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/
-
-
- /*---- FUNCION: void BMPescribirLinea(char *p, FILE *f,int bytes) --------------
-
- Descripción:
-
- Esta función escribe una línea en un fichero BMP.
-
- Parámetros:
-
- char *p : puntero a buffer que alberga la línea
- FILE *f : puntero al fichero
- int bytes : numero de bytes por línea
-
- Retorno:
-
- Puntero a la estructura de la imagen o NULL si hubo error
-
- ---- CODIGO: -----------------------------------------------------------------*/
-
- void BMPescribirLinea(char *p, FILE *f,int bytes)
- {
- fwrite(p,bytes,1,f);
- }
-
- /*---- FIN FUNCION -----------------------------------------------------------*/